/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.farent.solutions.plugins.aribaweb;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.spi.java.project.support.ui.PackageView;
import org.openide.WizardDescriptor.Panel;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.RequestProcessor;

public class AWMainComponentVisualPanel1 extends JPanel implements ActionListener, DocumentListener {

    private SourceGroup groups[];
    private Project project;
    private String expectedExtension;

    /** Creates new form AWMainComponentVisualPanel1 */
    public AWMainComponentVisualPanel1(Project p, SourceGroup[] groups) {
        this.project = p;
        this.groups = groups;
        for (SourceGroup sourceGroup : groups) {
            if (sourceGroup == null) {
                throw new NullPointerException();
            }
        }
//        souceGroupsCombo.addActionListener( this );
        initComponents();

        this.javaFileName.setEditable(false);
        souceGroupsCombo.setRenderer(new GroupListCellRenderer());
        packageCombo.setRenderer(PackageView.listRenderer());
    }

    void initValues(FileObject template, FileObject preselectedFolder) {
        projectName.setText(ProjectUtils.getInformation(project).getDisplayName());
        souceGroupsCombo.setModel(new DefaultComboBoxModel(groups));

        SourceGroup preselectedGroup = getPreselectedGroup(preselectedFolder);
        souceGroupsCombo.setSelectedItem(preselectedGroup);

        Object preselectedPackage = getPreselectedPackage(preselectedGroup, preselectedFolder, packageCombo.getModel());
        if (preselectedPackage != null) {
            packageCombo.getEditor().setItem(preselectedPackage);
        }
        final String baseName = template.getName();
        String activeName = baseName;
        if (preselectedFolder != null) {
            int index = 0;
            while (true) {
                FileObject _tmp = preselectedFolder.getFileObject(activeName, template.getExt());    //NOI18N
                if (_tmp == null) {
                    break;
                }
                activeName = baseName + ++index;
            }
        }
        className.setText(activeName);
        className.selectAll();

        String ext = template == null ? "" : template.getExt(); // NOI18N
        expectedExtension = ext.length() == 0 ? "" : "." + ext; // NOI18N

        updatePackages();

        updateText();

        className.getDocument().addDocumentListener(this);
        packageCombo.setEditable(true);
        Component packageEditor = packageCombo.getEditor().getEditorComponent();
        ((javax.swing.JTextField)packageEditor).getDocument().addDocumentListener( this );
    }

    private SourceGroup getPreselectedGroup(FileObject folder) {
        for (int i = 0; folder != null && i < groups.length; i++) {
            FileObject root = groups[i].getRootFolder();
            if (root.equals(folder) || FileUtil.isParentOf(root, folder)) {
                return groups[i];
            }
        }
        return groups[0];
    }

    private Object getPreselectedPackage(SourceGroup group, FileObject folder, ListModel model) {
        if (folder == null) {
            return null;
        }
        FileObject root = group.getRootFolder();

        String relPath = FileUtil.getRelativePath(root, folder);

        if (relPath == null) {
            // Group Root folder is no a parent of the preselected folder
            // No package should be selected
            return null;
        } else {
            // Find the right item.
            String name = relPath.replace('/', '.');
            /*
            int max = model.getSize();
            for (int i = 0; i < max; i++) {
            Object item = model.getElementAt(i);
            if (item.toString().equals(name)) {
            return item;
            }
            }
             */
            // Didn't find it.
            // #49954: should nonetheless show something in the combo box.
            return name;
        }
    }

    @Override
    public String getName() {
        return "Step #1";
    }

    private void updateText() {
        final Object selectedItem = souceGroupsCombo.getSelectedItem();
        String createdFileName;
        if (selectedItem instanceof SourceGroup) {
            SourceGroup g = (SourceGroup) selectedItem;
            FileObject rootFolder = g.getRootFolder();
            String packageName = getPackageFileName();
            String documentName = className.getText().trim();
            documentName = documentName + expectedExtension;
            createdFileName = FileUtil.getFileDisplayName(rootFolder)
                    + (packageName.startsWith("/") || packageName.startsWith(File.separator) ? "" : "/") + // NOI18N
                    packageName
                    + (packageName.endsWith("/") || packageName.endsWith(File.separator) || packageName.length() == 0 ? "" : "/") + // NOI18N
                    documentName;
        } else {
            //May be null iff nothing selected
            createdFileName = "";   //NOI18N
        }
        javaFileName.setText(createdFileName.replace('/', File.separatorChar)); // NOI18N
        String createdAwl = createdFileName.replace(expectedExtension, ".awl");
        awlFileName.setText(createdAwl.replace('/', File.separatorChar));
    }

    
    private RequestProcessor.Task updatePackagesTask = null;
    private static final ComboBoxModel WAIT_MODEL = new DefaultComboBoxModel(
            new String[]{
                "Please Wait..." // NOI18N
            });

    private void updatePackages() {
        final Object item = souceGroupsCombo.getSelectedItem();
        if (!(item instanceof SourceGroup)) {
            return;
        }
        WAIT_MODEL.setSelectedItem(packageCombo.getEditor().getItem());
        packageCombo.setModel(WAIT_MODEL);

        if (updatePackagesTask != null) {
            updatePackagesTask.cancel();
        }

        updatePackagesTask = new RequestProcessor("ComboUpdatePackages").post(new Runnable() {

            @Override
            public void run() {
                final ComboBoxModel model = PackageView.createListView((SourceGroup) item);
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        model.setSelectedItem(packageCombo.getEditor().getItem());
                        packageCombo.setModel(model);
                    }
                });
            }
        });
    }

    public String getPackageFileName() {

        String packageName = packageCombo.getEditor().getItem().toString();
        return packageName.replace('.', '/'); // NOI18N
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        className = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        projectName = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        souceGroupsCombo = new javax.swing.JComboBox();
        jLabel4 = new javax.swing.JLabel();
        packageCombo = new javax.swing.JComboBox();
        jLabel5 = new javax.swing.JLabel();
        javaFileName = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        awlFileName = new javax.swing.JTextField();

        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.jLabel1.text")); // NOI18N

        className.setText(org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.className.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.jLabel2.text")); // NOI18N

        projectName.setEditable(false);
        projectName.setText(org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.projectName.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.jLabel3.text")); // NOI18N

        souceGroupsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.jLabel4.text")); // NOI18N

        packageCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        org.openide.awt.Mnemonics.setLocalizedText(jLabel5, org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.jLabel5.text")); // NOI18N

        javaFileName.setEditable(false);
        javaFileName.setText(org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.javaFileName.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel6, org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.jLabel6.text")); // NOI18N

        awlFileName.setEditable(false);
        awlFileName.setText(org.openide.util.NbBundle.getMessage(AWMainComponentVisualPanel1.class, "AWMainComponentVisualPanel1.awlFileName.text")); // NOI18N

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel3)
                            .addComponent(jLabel4))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(projectName, javax.swing.GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE)
                            .addComponent(className, javax.swing.GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE)
                            .addComponent(souceGroupsCombo, 0, 396, Short.MAX_VALUE)
                            .addComponent(packageCombo, 0, 396, Short.MAX_VALUE)))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel5)
                            .addComponent(jLabel6))
                        .addGap(23, 23, 23)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(awlFileName, javax.swing.GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE)
                            .addComponent(javaFileName, javax.swing.GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE))))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(className, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(projectName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(souceGroupsCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(packageCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel5)
                    .addComponent(javaFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(awlFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(17, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField awlFileName;
    private javax.swing.JTextField className;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JTextField javaFileName;
    private javax.swing.JComboBox packageCombo;
    private javax.swing.JTextField projectName;
    private javax.swing.JComboBox souceGroupsCombo;
    // End of variables declaration//GEN-END:variables

    // ActionListener implementation -------------------------------------------
    @Override
    public void actionPerformed(java.awt.event.ActionEvent e) {
        if (souceGroupsCombo == e.getSource()) {
            updatePackages();
            updateText();
        } else if (packageCombo == e.getSource()) {
            updateText();
        } else if (packageCombo.getEditor() == e.getSource()) {
            updateText();
        }
    }

    // DocumentListener implementation -----------------------------------------
    public void changedUpdate(javax.swing.event.DocumentEvent e) {
        updateText();
    }

    public void insertUpdate(javax.swing.event.DocumentEvent e) {
        changedUpdate(e);
    }

    public void removeUpdate(javax.swing.event.DocumentEvent e) {
        changedUpdate(e);
    }

    /**
     * Displays a {@link SourceGroup} in {@link #rootComboBox}.
     */
    private static final class GroupListCellRenderer extends DefaultListCellRenderer/*<SourceGroup>*/ {

        public GroupListCellRenderer() {
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            String name;
            Icon icon;
            if (value == null) {
                name = ""; //NOI18N
                icon = null;
            } else {
                assert value instanceof SourceGroup;
                SourceGroup g = (SourceGroup) value;
                name = g.getDisplayName();
                icon = g.getIcon(false);
            }
            super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
            setIcon(icon);
            return this;
        }
    }

    public String getTargetJavaFileName() {
        String text = javaFileName.getText().trim();

        if ( text.length() == 0 ) {
            return null;
        }
        else {
            return text;
        }
    }

    public String getTargetClassName() {
        String text = className.getText().trim();

        if ( text.length() == 0 ) {
            return null;
        }
        else {
            return text;
        }
    }

    public String getTargetAWLFileName() {
        String text = awlFileName.getText().trim();

        if ( text.length() == 0 ) {
            return null;
        }
        else {
            return text;
        }

    }

    public String getTargetPackage() {
        String text = packageCombo.getEditor().getItem().toString();

        if ( text.length() == 0 ) {
            return null;
        }
        else {
            return text;
        }

    }

    public FileObject getRootFolder() {
        final Object selectedItem  = souceGroupsCombo.getSelectedItem();
        return (selectedItem instanceof SourceGroup) ? ((SourceGroup)selectedItem).getRootFolder() : null;
    }
}
